﻿using AForge.Video.DirectShow;

namespace VideoRecorder.Media;

public class WebCamHelper {
    /// <summary>
    /// 摄像头设备列表
    /// </summary>
    public static IEnumerable<FilterInfo> CameraDevices => new FilterInfoCollection(FilterCategory.VideoInputDevice).Cast<FilterInfo>();

    /// <summary>
    /// 获取摄像头信息,支持的分辨率、帧率
    /// </summary>
    /// <param name="deviceName">摄像头名称</param>
    public static IEnumerable<WebCamInfo> GetCameraInfos(string deviceName) {
        if (deviceName == null) return Array.Empty<WebCamInfo>();
        var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        if (videoDevices.Count == 0) return Array.Empty<WebCamInfo>();

        FilterInfo specDevice = null;
        foreach (FilterInfo it in videoDevices) {
            if (it.Name == deviceName) {
                specDevice = it;
                break;
            }
        }

        if (specDevice == null) return Array.Empty<WebCamInfo>();

        var device = new VideoCaptureDevice(specDevice.MonikerString);
        var capabilities = device.VideoCapabilities;

        return capabilities.Select(it => new WebCamInfo {
            Fps = it.AverageFrameRate,
            Width = it.FrameSize.Width,
            Height = it.FrameSize.Height,
            BitCount = it.BitCount
        }).OrderBy(it => it.Width * it.Height);
    }

    public static WebCamInfo? GetPreferCameraInfo(IReadOnlyList<WebCamInfo> list, int preferWidth = 800, int preferHeight = 600) {
        var count = list.Count;
        var perferResolution = preferWidth * preferHeight;
        for (var i = 0; i < count; i++) {
            var it = list[i];
            var resolution = it.Width * it.Height;
            if (resolution == perferResolution) return it;

            if (i < count - 1) {
                var next = list[i + 1];
                var nextResolution = next.Width * next.Height;
                if (resolution < perferResolution && perferResolution < nextResolution) {
                    return it;
                }
            }
        }

        return count > 0 ? list[0] : null;
    }

    /// <summary>根据fps获取帧间隔时间,最大支持30帧</summary>
    public static int GetFpsIntervalTime(ref int fps) {
        switch (fps) {
            default:
                fps = 15;
                return 50;

            case 15: return 50;
            case 20: return 40;
            case 25: return 31;
            case 30: return 28;
        }
    }

    /// <summary>根据fps获取帧间隔时间,最大支持30帧</summary>
    /// <param name="fps"></param>
    /// <returns></returns>
    public static int GetFpsIntervalTime(int fps) {
        return fps switch {
            15 => 50,
            20 => 40,
            25 => 31,
            30 => 28,
            _ => 50
        };
    }
}
